#include <fcntl.h>
#include "server.h"
#include "user.h"

static server_t server = {0};


void init_server_socket(uint16_t listenport){
    int serv_sock,flags;
    struct  sockaddr_in serv_addr;
    int option;
    socklen_t optlen = sizeof(option);


    serv_sock = socket(PF_INET,SOCK_STREAM,0);
    if(serv_sock == -1) return;
    memset(&serv_addr,0,sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(listenport);

    option = 1;
    setsockopt(serv_sock,SOL_SOCKET,SO_REUSEADDR,(void*)&option,optlen);

    if(bind(serv_sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) == -1){
        return;
    }

    if(listen(serv_sock,5) == -1){
        return;
    }

    flags = fcntl(server.server_sock,F_GETFL,0);
    fcntl(server.server_sock,F_SETFL,flags|O_NONBLOCK);
    
    server.init_ok = 1;
    server.server_sock = serv_sock;

    FD_ZERO(&server.writefds);
    FD_ZERO(&server.readfds);
    FD_ZERO(&server.errorfds);
    printf("server bind ok,port is %d\n",listenport);
}

void* server_thread(void* param){
    int ret;
    int client_sock;
    struct timeval timeout = {0};
    struct sockaddr_in clnt_addr;
    user_socket* user;
    socklen_t clnt_addr_size = sizeof(clnt_addr);
    init_server_socket(get_server_port());
    while(!server.server_exit){
        timeout.tv_sec = 1;
        FD_SET(server.server_sock,&server.readfds);
        ret = select(server.server_sock+1,&server.readfds,NULL,NULL,&timeout); 
        if(ret > 0){
            if(FD_ISSET(server.server_sock,&server.readfds)){                 
                client_sock = accept(server.server_sock,(struct sockaddr*)&clnt_addr,&clnt_addr_size);
                if(client_sock == -1){
                    printf("no accept\n");                    
                }
                else{
                    user = create_user();
                    user->sock = client_sock;
                    pthread_create(&server.th,NULL,user_thread,user);
                    printf("connect one client\n");
                    
                }
            }
        }
    }
    close(server.server_sock);
    return NULL;
}